#pragma once
#include <iostream>
#include <vector>
#include <utility>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#include <map>
#include <cstring>

using namespace std;

typedef vector<vector<char> > Board;
const int N = 9;

class Sudoku
{
    friend class SudokuTest;  // 声明测试类为友元类

private:

    bool rows[N][N];
    bool columns[N][N];
    bool blocks[N][N];

public:
    vector<Board> result; 
    vector<pair<int, int> > spaces; 

public:
    Sudoku() { initSudoku(); }

    void initSudoku();

    void addResult(Board& board); 

    void flip(int i, int j, int digit);

    vector<Board> solveSudoku(Board board);

    void DFS(Board& board, int pos); 

    void getResult();

    bool checkBoard(Board& board);

    void printBoard(Board& board);

    Board generateBoard(int holes, bool mustUnique); 

    vector<int> getRand9();

    void copySquare(Board& board, size_t src_x, size_t src_y, bool isRow);

    std::vector<std::vector<bool>> getRows() const {
        std::vector<std::vector<bool>> result(N, std::vector<bool>(N));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                result[i][j] = rows[i][j];
            }
        }
        return result;
    }

    std::vector<std::vector<bool>> getColumns() const {
        std::vector<std::vector<bool>> result(N, std::vector<bool>(N));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                result[i][j] = columns[i][j];
            }
        }
        return result;
    }

    std::vector<std::vector<bool>> getBlocks() const {
        std::vector<std::vector<bool>> result(N, std::vector<bool>(N));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                result[i][j] = blocks[i][j];
            }
        }
        return result;
    }
};

void writeFile(vector<Board> boards, ofstream& f);
vector<Board> readFile(string filePath);
void generateGame(int gameNum, vector<int> digCount, ofstream& outfile, Sudoku& s, bool mustUnique);